using System;
using System.Collections.Generic;
using System.Text;

namespace SUnit.Core
{
    public class TestRunner
    {
        #region Declarations

        private TestInfo _tests;

        #endregion

        #region Constructor

        public TestRunner(TestInfo tests)
        {
            _tests = tests;
        }

        #endregion

        #region Public Events

        public event TestCompletedEventHandler TestCompleted;

        #endregion

        #region Public Properties

        public int TestCount
        {
            get { return _countTests(_tests);  }
        }

        #endregion

        #region Public Methods

        public void Run(Tester tester)
        {
            _run(_tests, tester);
        }

        #endregion

        #region Private Methods

        private int _countTests(TestInfo test)
        {
            //Si no tiene subtests, lo cuento
            if (test.Tests.Count == 0)
                return 1;

            //Sino, cuento los tests de cada uno de sus hijos, recursivamente
            int testCount = 0;
            foreach (TestInfo child in test.Tests)
                testCount += _countTests(child);
            
            return testCount;
        }

        private void _run(TestInfo test, Tester tester)
        {
            //Caso base, se trata de una hoja:
            //Corro el test y disparo el evento TestCompleted
            if (test.Tests.Count == 0)
            {
                TestResult result = tester.Test(test);

                //Disparo el evento
                if (TestCompleted != null) 
			    {
                    TestCompletedEventArgs args = new TestCompletedEventArgs(result);
                    TestCompleted(test, args);
			    }
                return;
            }

            //Si no es una hoja, corro todos sus hijos
            foreach (TestInfo child in test.Tests)
                _run(child, tester);
        }

        #endregion
    }

    public delegate void TestCompletedEventHandler(object sender, TestCompletedEventArgs e);

    public class TestCompletedEventArgs : EventArgs
    {
        private TestResult _result = null;

        public TestCompletedEventArgs(TestResult result)
        {
            _result = result;
        }

        public TestResult Result
        {
            get { return _result; }
        }        
    }

}
